package loader;

import java.util.*;
import java.io.*;

import data_stuct.*;

/**
 * Class for loading data from the four d.b. tables
 * 
 * @author Majid Mallis
 */
public class Loader {

    /**
     * This vector of entries contains the full database
     */
    private Vector<Entry> db = new Vector<Entry>();
    private Vector<Couple> typesCA = new Vector<Couple>();

    /**
     * The year corresponding to the database. initialized to 1981
     */
    private String ANNEE = "1981";

    /**
     * Constructor: loads the pertinent database from the four tables
     * 
     * @param ETAB0X The table that contains activity centers data
     * @param ETABCLSC The table that contains activity centers names
     * @param DONFIN0X The table that contains the pertinent data
     * @param DONADD0X the table that contains additional costs information
     * @return Nothing
     */
    public Loader(FileReader DONFIN0X, FileReader ETAB0X, FileReader ETABCLSC,
            FileReader DONADD0X, FileReader UNIT0X, FileReader TYPECA,
            String ANNEE) {

        // set the year
        this.ANNEE = ANNEE;

        // load pertinent data - Table #3
        loadPertinentData(DONFIN0X);

        // load activity centers data - Table #2
        loadActivityCenterData(ETABCLSC);

        // load activity centers names - Table #1
        loadActivityCenterNames(ETAB0X);

        // load additional data - Table #4
        // loadAdditionalData(DONADD0X);

        // load units data - other tables
        loadUnitData(UNIT0X);

        // load activity centers types - stable table
        loadActivityCenterTypes(TYPECA);

    }

    /**
     * Returns The full pertinent database
     * 
     * @return The pertinent database vector
     */
    public Vector<Entry> getDb() {
        return db;
    }

    /**
     * Sets the database vector with data contained into parameter
     * 
     * @param db The database vector
     */
    public void setDb(Vector<Entry> db) {
        this.db = db;
    }

    /**
     * 
     * @return A table containing types of CA
     */
    public Vector<Couple> getTypesCA() {
        return typesCA;
    }

    /**
     * 
     * @param typeCA The table of CA types
     */
    public void setTypesCA(Vector<Couple> typeCA) {
        this.typesCA = typeCA;
    }

    /**
     * Loads the main information of SIFO DB. this information contains global
     * costs for each center of activity
     * 
     * @param fr The data FileReader
     */
    private void loadPertinentData(FileReader fr) {

        try {
            BufferedReader br = new BufferedReader(fr);
            String line;
            char[] temp = null;

            while ((line = br.readLine()) != null) {

                Entry entry = new Entry();

                // assign RSS
                line.getChars(5, 7, entry.RSS, 0);

                // assign CORPO
                line.getChars(8, 16, entry.CORPO, 0);

                // assign CENT_RES
                line.getChars(17, 19, entry.CENT_RES, 0);

                // assign GROUPE
                line.getChars(20, 22, entry.GROUPE, 0);

                // assign CENT_ACT
                line.getChars(23, 27, entry.CENT_ACT, 0);

                // assign UNIVERS
                line.getChars(28, 30, entry.UNIVERS, 0);

                // assign SSDOM
                line.getChars(31, 35, entry.SSDOM, 0);

                // assign HRS_TRAV
                temp = new char[10];
                line.getChars(36, 46, temp, 0);
                entry.HRS_TRAV = Integer.parseInt(new String(temp));

                // assign HRS_REM
                temp = new char[10];
                line.getChars(47, 57, temp, 0);
                entry.HRS_REM = Integer.parseInt(new String(temp));

                // assign SAL_AV
                temp = new char[10];
                line.getChars(58, 68, temp, 0);
                entry.SAL_AV = (double) Integer.parseInt(new String(temp));

                // assign AUT_DEP
                temp = new char[10];
                line.getChars(69, 79, temp, 0);
                entry.AUT_DEP = (double) Integer.parseInt(new String(temp));

                // assign DEDUC
                temp = new char[10];
                line.getChars(80, 90, temp, 0);
                entry.DEDUC = (double) Integer.parseInt(new String(temp));

                // assign CT_BRUT
                temp = new char[10];
                line.getChars(91, 101, temp, 0);
                entry.CT_BRUT = (double) Integer.parseInt(new String(temp));

                // assign CT_NET
                temp = new char[10];
                line.getChars(102, 112, temp, 0);
                entry.CT_NET = (double) Integer.parseInt(new String(temp));

                db.add(entry);
            }
        } catch (Exception e) {
            System.err.print(e.getMessage());
        }
    }

    /**
     * Loads information defining centers of activities
     * 
     * @param fr The data FileReader
     */
    private void loadActivityCenterData(FileReader fr) {
        try {
            BufferedReader br = new BufferedReader(fr);
            String line;
            char[] corpo = new char[8];

            while ((line = br.readLine()) != null) {

                char[] DERN_AN = new char[4];

                // Verify if the activity center still existing
                line.getChars(33, 37, DERN_AN, 0);
                // verify if ANNEE = DERN_AN
                if (ANNEE.compareTo(new String(DERN_AN)) == 0) {

                    // find the corresponding entry (same CORPO)
                    line.getChars(0, 8, corpo, 0);
                    for (Entry current_entry : db) {
                        // verify if corpo = current_entry.corpo
                        if (new String(corpo).compareTo(new String(
                                current_entry.CORPO)) == 0) {

                            // assign CP
                            line.getChars(9, 15, current_entry.CP, 0);

                            // assign CODMUNIC
                            line.getChars(16, 21, current_entry.CODMUNIC, 0);

                            // assign CLSC
                            line.getChars(22, 27, current_entry.CLSC, 0);

                            // assign PREM_AN
                            line.getChars(28, 32, current_entry.PREM_AN, 0);
                        }
                    }
                }
            }
        } catch (Exception e) {
            System.err.print(e.getMessage());
        }
    }

    /**
     * Loads names of activities centers
     * 
     * @param fr The data FileReader
     */
    private void loadActivityCenterNames(FileReader fr) {
        try {
            BufferedReader br = new BufferedReader(fr);
            String line;
            char[] corpo = new char[8];

            while ((line = br.readLine()) != null) {

                // find the corresponding entry (same CORPO)
                line.getChars(0, 8, corpo, 0);
                for (Entry current_entry : db) {
                    if (new String(corpo).compareTo(new String(
                            current_entry.CORPO)) == 0) {

                        // assign NOMCORPO
                        line.getChars(11, 69, current_entry.NOMCORPO, 0);
                    }
                }
            }
        } catch (Exception e) {
            System.err.print(e.getMessage());
        }
    }

    /**
     * Loads additional costs for each center of activities
     * 
     * @param fr The data FileReader
     */
    @SuppressWarnings("unused")
    private void loadAdditionalData(FileReader fr) {
        try {
            BufferedReader br = new BufferedReader(fr);
            String line;
            char[] temp;
            char[] rss = new char[8];
            char[] cent_res = new char[4];
            char[] univers = new char[2];
            char[] ssdom = new char[4];

            while ((line = br.readLine()) != null) {

                // find the corresponding entry (same rss, cent_res, univers
                // and
                // ssdom)
                line.getChars(0, 8, rss, 0);
                line.getChars(9, 13, cent_res, 0);
                line.getChars(11, 13, univers, 0);
                line.getChars(14, 18, ssdom, 0);
                for (Entry current_entry : db) {
                    if (new String(rss)
                            .compareTo(new String(current_entry.RSS)) == 0
                            && new String(cent_res).compareTo(new String(
                                    current_entry.CENT_RES)) == 0
                            && new String(univers).compareTo(new String(
                                    current_entry.UNIVERS)) == 0
                            && new String(ssdom).compareTo(new String(
                                    current_entry.SSDOM)) == 0) {

                        // assign COUT
                        temp = new char[10];
                        line.getChars(19, 29, temp, 0);
                        current_entry.COUT = (double) Integer
                                .parseInt(new String(temp));
                    }
                }
            }
        } catch (Exception e) {
            System.err.print(e.getMessage());
        }
    }

    /**
     * Loads Units data for each center of activities
     * 
     * @param fr The data FileReader
     */
    private void loadUnitData(FileReader fr) {
        try {
            BufferedReader br = new BufferedReader(fr);
            String line;
            char[] temp;
            char[] corpo = new char[8];

            char[] cent_act = new char[4];
            char[] unit_type = new char[3]; // UMA or UMB
            while ((line = br.readLine()) != null) { // find the
                // corresponding entry (same corpo and cent_act)
                line.getChars(0, 8, corpo, 0);
                line.getChars(9, 13, cent_act, 0);
                line.getChars(14, 17, unit_type, 0);
                for (Entry current_entry : db) {
                    if (new String(corpo).compareTo(new String(
                            current_entry.CORPO)) == 0
                            && new String(cent_act).compareTo(new String(
                                    current_entry.CENT_ACT)) == 0) {
                        // assign number of Units
                        temp = new char[line.length() - 18];
                        line.getChars(18, line.length(), temp, 0);
                        if (unit_type[2] == 'A') {
                            current_entry.UnitA = Integer.parseInt(new String(
                                    temp));
                        }
                        else {
                            current_entry.UnitB = Integer.parseInt(new String(
                                    temp));
                        }
                    }
                }
            }
        } catch (Exception e) {
            System.err.print(e.getMessage());
        }
    }

    /**
     * Loads types for each center of activities
     * 
     * @param fr The data FileReader
     */
    private void loadActivityCenterTypes(FileReader fr) {
        try {
            BufferedReader br = new BufferedReader(fr);
            String line;

            while ((line = br.readLine()) != null) {
                char[] CA = new char[4];
                char[] type = new char[1];
                Couple c = new Couple();

                line.getChars(0, 4, CA, 0);
                c.setCA(CA);

                line.getChars(5, 6, type, 0);
                c.setType(type[0]);

                typesCA.add(c);
            }
        } catch (Exception e) {
            System.err.print(e.getMessage());
        }
    }

    /**
     * converts a vector of entries to a 2-dimensional-array of string
     * 
     * @param v The input vector
     * @return the 2-dimensional output array
     */
    public Object[][] toPrintableTable(Vector<Entry> v) {

        Object[][] dataTable = new Object[v.size()][16];
        int i = 0;

        for (Entry e : v) {
            Object[] temp = new Object[16];
            temp[0] = new String(e.RSS);
            temp[1] = new String(e.CORPO);
            temp[2] = new String(e.NOMCORPO);

            // format postal code
            temp[3] = new String(e.CP, 0, 3) + " " + new String(e.CP, 3, 3);

            temp[4] = new String(e.CODMUNIC);
            temp[5] = new String(e.CLSC);
            temp[6] = new String(e.PREM_AN);
            temp[7] = new String(e.CENT_RES);
            temp[8] = new String(e.GROUPE);
            temp[9] = new String(e.CENT_ACT);
            temp[10] = new String(e.UNIVERS);
            temp[11] = new String(e.SSDOM);
            temp[12] = e.HRS_TRAV;
            temp[13] = e.CT_BRUT;
            temp[14] = e.UnitA;
            temp[15] = e.UnitB;

            dataTable[i] = temp;
            i++;
        }

        return dataTable;

    }
}
